package main

import "fmt"
import (
	"sync"
	"time"
)

type ThreadSafeSet struct {
	sync.RWMutex //读写互斥体
	s []int //写义一个切片
}

func (set *ThreadSafeSet) Iter() <-chan interface{} { //为这个结构体定义一个方法,返回值为通道并阻塞中，在等待接收传来的数据,返回的是一个地址
	ch := make(chan interface{})
	//make创建一个通道，类型是接口类型，可以接收任何类型,因为通道属于无缓冲的，每次只能写入一次数据。所以设置一个缓冲数
	//所以建用有缓冲的通道。比如100
	go func() { //创建一个goroutine
		set.RLock() //读锁
		for elem := range set.s { //遍历切片
		//fmt.Println(elem)
		fmt.Println("+++++++++++++")
			ch <- elem //把遍历的结果写入通道中,但是到这里写入数据，没人去取，所以阻塞了，就不往下执行了
			//因为主线程等待５秒后自动就结构主线程了。所以就什么都不输出。只输出主线程的通道了
			//fmt.Println(ch) //引用地址都是同一个
			fmt.Println("--------------")
			fmt.Println("get:", elem, ",") //输出写入通道中的数据
		}

		close(ch) //关闭通道
		set.RUnlock() //解锁

	}()
	return ch //返回通道中的数据
}

func main() {
	read()
	//unRead() //调用函数
}
func read() {
	set := ThreadSafeSet{} //创建一个结构体对象
	set.s = make([]int, 100) //创建一个切片，类型[]int,长度100
	ch := set.Iter() //执行方法
	closed := false //变量closed bool,false
	for { //元限循环
		select { //选择执行
		case v, ok := <-ch: //遍历通道中的数据
			if ok { //如果true
				fmt.Println("read:", v, ",") //输出值
			} else {
				closed = true //否则closed为true
			}
		}
		if closed { //true
			fmt.Print("closed") //输出closed，被关闭
			break//跳出循环
		}
	}
	fmt.Print("Done")
}

func unRead() { //创建一个函数
	set := ThreadSafeSet{} //定义一个结构体对象
	set.s = make([]int, 100) //创建一个切片 长度为100
	ch := set.Iter() //调用方法Iter()
	_ = ch
	//aaa:=<-ch
	//fmt.Println(aaa)
	time.Sleep(5 * time.Second)
	fmt.Print("Done")
}
